package com.ruoyi.cs.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.Response;
import com.ruoyi.common.utils.CommonUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.common.utils.pay.FXPayConfig;
import com.ruoyi.common.utils.pay.HCPayConfig;
import com.ruoyi.common.utils.pay.SignUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.cs.domain.TRecharge;
import com.ruoyi.cs.domain.TUser;
import com.ruoyi.cs.domain.vo.FXPayNotifyParam;
import com.ruoyi.cs.mapper.TRechargeMapper;
import com.ruoyi.cs.mapper.TUserMapper;
import com.ruoyi.cs.service.CommonService;
import com.ruoyi.cs.service.IFUXINPayService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@Service
@SuppressWarnings("all")
public class FUXINPayServiceImpl implements IFUXINPayService {
    private Logger log = LoggerFactory.getLogger(FUXINPayServiceImpl.class);
    @Autowired
    private TUserMapper tUserMapper;
    @Autowired
    private CommonService commonService;
    @Autowired
    private TRechargeMapper tRechargeMapper;

    @Override
    public Response<Map> recharge(String userId, BigDecimal czMoney, String czEquipment,String czType) throws Exception {
        TUser tUser = tUserMapper.selectTUserById(userId);
        BigDecimal giveFee = new BigDecimal("0");
        try {
            giveFee = commonService.rechargeVerification(tUser, czMoney);
        } catch (Exception e) {
            return Response.fail(e.getMessage());
        }
        Integer goodsId = CommonUtils.getCzGoodsId(Constants.CZGOODSID,czMoney);
        if(goodsId == null){
            return  Response.fail("无此对应的充值金额");
        }
        String out_trade_no = DateUtils.dateTimeNow() + IdUtils.fastUUID().substring(0, 8);
        Map<String, String> map = new HashMap<>();
        map.put("sdorderno", out_trade_no);
        map.put("appid", FXPayConfig.applyId);
        map.put("goods_id", goodsId.toString());
        map.put("sign", SignUtils.signFXNotify(map, FXPayConfig.applykey));
        if(Constants.WECHATPAY.equals(czType)){
            map.put("paytype", "wx");
        }else {
            map.put("paytype", "alipaywap");
        }
        map.put("time", System.currentTimeMillis()+"");
        map.put("buyers", tUser.getUserName());
        String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
        map.put("client_ip",ip);
//        map.put("steam_url", null);
        String result = HttpUtils.http(FXPayConfig.applyPay,map);
        JSONObject jsonObject = JSON.parseObject(result);
        String url = null;
        if(jsonObject.getInteger("status") == 200){
            url =  jsonObject.getString("result");
        }else {
            return  Response.fail("调起支付失败:"+jsonObject.getString("error"));
        }
        String picurl = null;
        try {
            /**生产二维码图片*/
            picurl = commonService.scQrCodeImge(url);
        } catch (Exception e) {
            log.error("富信支付生产二维码订单异常:{}", e.getMessage());
            e.printStackTrace();
            return Response.fail("发送请求失败");
        }

        TRecharge tRecharge = new TRecharge();
        tRecharge.setUserId(userId);
        tRecharge.setCzId(out_trade_no);
        tRecharge.setDelFlag(Constants.SUCCESS);

        if(Constants.WECHATPAY.equals(czType)){
            tRecharge.setCzType(Constants.WECHATPAY);
        }else {
            tRecharge.setCzType(Constants.ALIPAY);
        }
        /**支付结果  0 待充值 1充值成功 2充值失败*/
        tRecharge.setCzStatus(Constants.CZSTATUS0);
        /**交易类型*/
        tRecharge.setCzEquipment(czEquipment);
        tRecharge.setCreateTime(DateUtils.getNowDate());
        tRecharge.setGiveFee(giveFee);
        tRecharge.setCzMoney(czMoney);
        tRecharge.setCzPlatform(Constants.CZPLATFORM4);
        tRecharge.setUserType(tUser.getUserType());
        if (StringUtils.isNotEmpty(tUser.getUserPromotersId())) {
            tRecharge.setUserPromotersId(tUser.getUserPromotersId());
        }
        int count = tRechargeMapper.insertTRecharge(tRecharge);
        BigDecimal fee = czMoney.multiply(new BigDecimal(6.5)).setScale(2, BigDecimal.ROUND_HALF_UP);
        if (count > 0) {
            Map resultMap = new HashMap();
            resultMap.put("picUrl", picurl);
            resultMap.put("czId", out_trade_no);
            resultMap.put("totalFee", czMoney);
            resultMap.put("url", url);
            log.info("富信支付订单生产：参数信息：{}，支付金额：{},订单号：{}", JSON.toJSONString(tRecharge), fee, out_trade_no);
            return Response.success(resultMap);
        } else {
            log.error("富信支付充值记录表插入失败：参数信息：{}，支付金额：{},订单号：{}", JSON.toJSONString(tRecharge), fee, out_trade_no);
            return Response.fail("充值窗口异常，请联系管理员处理!");
        }
    }

    @Override
    public String notify(FXPayNotifyParam fxPayNotifyParam) {
        String paramsJson = JSON.toJSONString(fxPayNotifyParam);
        log.info("富信支付回调，{}", JSON.toJSONString(fxPayNotifyParam));
        try {
            String sdorderno = fxPayNotifyParam.getSdorderno();
            String platform_id = fxPayNotifyParam.getPlatform_id();
            String goods_id = fxPayNotifyParam.getGoods_id();
            String paytype = fxPayNotifyParam.getPaytype();
            String price = fxPayNotifyParam.getPrice();
            String status = fxPayNotifyParam.getStatus();
            String error = fxPayNotifyParam.getError();
            String sign = fxPayNotifyParam.getSign();
            // 生成查询签名
            Map<String, String> map = JSON.parseObject(paramsJson, new TypeReference<Map<String, String>>() {});
            String  signVerified = SignUtils.signFXNotify(map,FXPayConfig.applykey);
            if (signVerified.equals(sign)) {
                TRecharge tRecharge = tRechargeMapper.selectTRechargeById(sdorderno);
                String platform = tRecharge == null ? "" : tRecharge.getCzPlatform();
                Map<String, String> paramsMap = JSONObject.parseObject(paramsJson, Map.class);
                log.info("富信回调签名认证成功");
                if (tRecharge != null) {
                    BigDecimal bg = tRecharge.getCzMoney();
                    BigDecimal fee = bg.multiply(new BigDecimal(6.5)).setScale(2, BigDecimal.ROUND_HALF_UP);
                    if(fee.compareTo(new BigDecimal(price)) != 0){
                        log.error("支付金额不对等,请求参数:{}",paramsJson);
                        return "0";
                    }
                    if(Constants.CZSTATUS0.equals(tRecharge.getCzStatus())){
                        /**支付状态 0 未支付 1 支付成功 2 支付失败 3 投诉中 4 已退款*/
                        if ("1".equals(status)) {
                            commonService.czSuccessHandle(tRecharge,sdorderno,platform_id,paramsJson);
                        } else if ("2".equals(status)) {
                            /**充值失败处理*/
                            commonService.czFailHandle(tRecharge,sdorderno,platform_id,paramsJson);
                        } else {
                            log.error("没有处理回调业务，交易状态：{},params:{}", status, paramsJson);
                        }
                    }else {
                        log.error("没有处理回调业务，交易状态：{},params:{}", status, paramsJson);
                    }
                    return "1";
                } else {
                    log.error("查询充值订单信息为空,请求参数：{}", paramsJson);
                    return "0";
                }
            } else {
                log.info("富信回调签名认证失败，signVerified=false, paramsJson:{}", paramsJson);
                return "0";
            }
        } catch (Exception e) {
            log.error("回调异常,paramsJson:{},errorMsg:{}", paramsJson, e.getMessage());
            return "0";
        }
    }
    public Map<String, String> convertRequestParamsToMap(HttpServletRequest request) {
        Map<String, String> retMap = new HashMap<String, String>();
        Set<Map.Entry<String, String[]>> entrySet = request.getParameterMap().entrySet();
        for (Map.Entry<String, String[]> entry : entrySet) {
            String name = entry.getKey();
            String[] values = entry.getValue();
            int valLen = values.length;
            if (valLen == 1) {
                retMap.put(name, values[0]);
            } else if (valLen > 1) {
                StringBuilder sb = new StringBuilder();
                for (String val : values) {
                    sb.append(",").append(val);
                }
                retMap.put(name, sb.toString().substring(1));
            } else {
                retMap.put(name, "");
            }
        }
        return retMap;
    }
}
